/** \file 
 *  \brief Archivo usado para SO Linux.
 *
 *  Este archivo contiene la definicon de las funciones de 
 *  de acceso al puerto serie, destinadas a SO tipo Linux
 *
 */

#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <sys/ioctl.h>
#include <pthread.h>
    
#include <termios.h> /* POSIX terminal control definitions */

#ifndef _SERIAL_PORT_H_
#define _SERIAL_PORT_H_

#define INVALID_HANDLE_VALUE -1
#define NONE      0    
#define RTSCTS    1
#define HARD      1
#define XONXOFF   2
#define SOFT      2
    
struct serial_callback_params_t {
    bool  (*funct)(int * port, void *params);
    void * params;
    int * port;
};

/** \var int Open_Port(char COMx[], int flags = O_RDWR)
 *  \brief Abre el puerto de comunicaciones
 *  \param COMx es el puerto a abrir "/dev/ttyS0","/dev/ttyS1","/dev/ttyACM0","/dev/ttyUSB0",...
 *  \param flags indica el modo de apertura del puerto: =_RDWR, O_RDONLY ó O_WRONLY
 *  \return El manejador del puerto
 *  \ingroup HeaderLinux
 */
int Open_Port(const char COMx[], int flags);

    
/** \var struct termios Get_Configure_Port(int fd)
 *  \brief Devuelve la configuracion Actual del Puerto serie 
 *  \param fd Es el manejador del puerto
 *  \return Una estructuracon struct termios con la configuracion actual del puerto
 *  \ingroup HeaderLinux
 */  
bool Get_Configure_Port(int fd, struct termios * Oldtio);
    
    
/** 
 *  \brief Configura el puerto serie 
 *  \param fd Es el manejador del puerto 
 *  \param BaudRate Es la velocidad del puerto
 *  \param CharParity indica el numero de bits de la transmision "8N1","7E1","7O1","7S1" 
 *  \return Una estructuracon Bcd con la configuracion del puerto
 *  \ingroup HeaderLinux
 */    
bool Configure_Port(int fd,unsigned int BaudRate,const char *CharParity, struct termios *newtio);

    
/** \var int Set_Configure_Port(int fd,struct termios Porttermio)
 *  \brief Coloca la configuracion en el puerto serie
 *  \param fd Es el manejador del puerto 
 *  \param Porttermio es la configuracion del puerto
 *  \return true si todo fue bien o false si no 
 *  \ingroup HeaderLinux
 */  
bool Set_Configure_Port(int fd,struct termios newtio);
    
    
/** \var long Write_Port(int fd,char Data[],int SizeData)
 *  \brief Escribe en el puerto serie
 *  \param fd Es el manejador del puerto 
 *  \param Data Es el dato a mandar
 *  \param SizeData es el tamaño del dato
 *  \return En caso de éxito, se devuelve el número de bytes escritos (cero 
 *          indica que no se ha escrito nada). En caso de error, se devuelve -1 
 *  \ingroup HeaderLinux
 */
long Write_Port(int fd,unsigned char Data[],int SizeData);
    
    
/** \var long Read_Port(int fd,char *Data,int SizeData)
 *  \brief Recibe datos en el puerto serie
 *  \param fd Es el manejador del puerto 
 *  \param Data Es el arreglo donde se almacenarán los datos recibidos
 *  \param SizeData es el tamaño del arreglo
 *  \return En caso de éxito, se devuelve el número de bytes recibidos (cero 
 *          indica que no se ha recibido nada). En caso de error, se devuelve -1 
 *  \ingroup HeaderLinux
 */  
long Read_Port(int fd,unsigned char *Data,int SizeData);

    
/** \var long Gets_Port(int fd,char *Data,int SizeData)
 *  \brief Recibe datos en el puerto serie,lee hasta encontrar un 0x0A,0x0D  
 *         (rellenando el siguiente byte con un cero - "solo si existe")   
 *         o hasta completar SizeData caracteres.
 *  \param fd Es el manejador del puerto 
 *  \param Data Es el arreglo donde se almacenarán los datos recibidos
 *  \param SizeData es el tamaño maximo del arreglo
 *  \return En caso de éxito, se devuelve el número de bytes recibidos (cero 
 *          indica que no se ha recibido nada). En caso de error, se devuelve -1 
 *  \ingroup HeaderLinux    
 */
long Gets_Port(int fd,char *Data,int SizeData);

    
/** \var Getc_Port(int fd,char *Data)
 *  \brief Recibe un caracter en el puerto serie.
 *  \param fd Es el manejador del puerto 
 *  \param Data Es el dato(8-bit) a mandar
 *  \return En caso de éxito, se devuelve el número de bytes recibidos (cero 
 *          indica que no se ha recibido nada). En caso de error, se devuelve -1 
 *  \ingroup HeaderLinux    
 */    
long Getc_Port(int fd,char *Data);


/** \var int Kbhit_Port(int fd)
 *  \brief Indica el numero de caracteres disponible en el buffer de entrada.
 *  \param fd Es el manejador del puerto. 
 *  \return El numero de caracteres en el buffer de recepcion.
 *  \ingroup HeaderLinux    
 */   
int Kbhit_Port(int fd);
    

/** \var bool Close_Port(int hComm)
 *  \brief Cierra el puerto serie.
 *  \param fd Es el manejador del puerto. 
 *  \return true si se ha cerrado el Puerto y false en el caso contrario.
 *  \ingroup HeaderLinux    
 */    
bool Close_Port(int fd);


/** \var bool Set_Hands_Haking(int fd,int FlowControl)
 *  \brief Configura el control de flujo en el puerto serie
 *  \param fd Es el manejador del puerto. 
 *  \param FlowControl 
 *                     0    Ninguno<br>                                            
 *                     1    RTS/CTS<br>                                             
 *                     2    Xon/Xoff<br>                                            
 *                     3    DTR/DSR  
 *  \return true si todo fue bien y false si no lo fue.
 *  \ingroup HeaderLinux    
 */    
bool Set_Hands_Haking(int fd,int FlowControl);


/** \var bool Set_RThreshold(int fd,int n)
 *  \brief configura el numero minimo de caracteres que permitira
 *         que se ejecute la lectura del puerto
 *  \param fd Es el manejador del puerto. 
 *  \param n  es el numero de caracteres que activara la lectura
 *  \return true si todo fue bien y false si no lo fue.
 *  \ingroup HeaderLinux    
 */        
bool Set_RThreshold(int fd,int n);

    
/** \var bool Set_BaudRate(int fd,unsigned int BaudRate)
 *  \brief configura la  velocidad puerto serie
 *  \param fd Es el manejador del puerto. 
 *  \param BaudRate Es la velocidad del PUerto
 *  \return true si todo fue bien y false si no lo fue.
 *  \ingroup HeaderLinux    
 */    
bool Set_BaudRate(int fd,unsigned int BaudRate);
	


/** \var bool Set_Time(int fd,unsigned int Time, unsigned int chars)
 *  \brief configura Temporizador para read y write
 *  \param fd Es el manejador del puerto. 
 *  \param Time Tiempo entre bits, T=Time*0.1s, para tamaño total de time-out   
 *               en read y write.<br>
 *               Timeout = (Time *0.1* number_of_bytes) seg 
 *  \params chars Numero de caracteres a leer antes de volver del read.
 *  \return true si todo fue bien y false si no lo fue.
 *  \ingroup HeaderLinux    
 */  
bool Set_Time(int fd,unsigned int Time, unsigned int chars);

    
/** \var bool IO_Blocking(int fd,int Modo)
 *  \brief configura Temporizador para read y write
 *  \param fd Es el manejador del puerto. 
 *  \param Modo<br>
 *   true : Modo bloqueante<br>                                          
 *   false: Modo no bloqueante 
 *  \return true si todo fue bien y false si no lo fue.
 *  \ingroup HeaderLinux    
 */  
bool IO_Blocking(int fd,int Modo) ;


/** \var bool Clean_Buffer(int fd)
 *  \brief Termina las operaciones de lectura y escritura pendientes y limpia
 *         las colas de recepción y de transmisión.
 *  \param fd Es el manejador del puerto. 
 *  \return true si todo fue bien y false si no lo fue.
 *  \ingroup HeaderLinux    
 */  
bool Clean_Buffer(int fd) ;

    
/** \var bool Setup_Comm(int fd,unsigned long InQueue,unsigned long OutQueue) 
 *  \brief Especifica el tamaño en Bytes del buffer de entrada y salida
 *  \param fd Es el manejador del puerto. 
 *  \param InQueue Especifica el tamaño en Bytes del buffer de entrada, se 
 *                 Recomienda el uso de numero pares.
 *  \param OutQueue Especifica el tamaño en Bytes del buffer de salida, se 
 *                 Recomienda el uso de numero pares.
 *  \return true si todo fue bien y false si no lo fue.
 *      
 */  
bool Setup_Buffer(int fd,unsigned long InQueue,unsigned long OutQueue) ;

    
/** \var pthread_t Create_Thread_Port(int *fd)
 *  \brief Se usa para crear un hilo que ejecuta la funcion <br>
 *         SERIAL_PORT_EVENT(int *hPort) <br>
 *         cuando se recibe un caracter por el puerto serie.
 *  \param fd Es el manejador del puerto. 
 *  \return El manejador del hilo creado 
 *  \ingroup HeaderLinux    
 */

pthread_t Create_Thread_Port(int *fd, bool (*funct)(int *,void *), void *params) ;

#endif
